package org.nlp2rdf.navigator.client;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

import org.nlp2rdf.navigator.client.common.ExampleDTO;
import org.nlp2rdf.navigator.client.common.LearnedConceptDTO;
import org.nlp2rdf.navigator.client.common.LearnedConceptDTO.MyExamples;
import org.nlp2rdf.navigator.client.functionality.ExampleWidget;
import org.nlp2rdf.navigator.client.functionality.TitleWidget;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class PositiveNegativeWidget extends Composite {

	// @SuppressWarnings("unused")
	// final private Application app;

	private VerticalPanel positiveExampleTable = new VerticalPanel();;
	private Map<String, ExampleDTO> positiveExampleDTOs = new LinkedHashMap<String, ExampleDTO>();

	private VerticalPanel negativeExampleTable = new VerticalPanel();;
	private Map<String, ExampleDTO> negativeExampleDTOs = new LinkedHashMap<String, ExampleDTO>();

	private TitleWidget titleWidget = new TitleWidget("Learning Input", (Panel) null);

	private static String learnButtonLabelInsufficientExamples = "start learning (needs 1 pos and 1 neg example)";
	private static String learnButtonLabelEnabled = "start learning";
	private static String learnButtonLabelLearning = "learning...";
	private Button learnButton = new Button(learnButtonLabelInsufficientExamples);

	public PositiveNegativeWidget(final Application app) {
		// disable hiding
		this.titleWidget.getBottom().clear();
		this.titleWidget.getBottom().add(learnButton);
		this.titleWidget.getTop().setCellVerticalAlignment(learnButton, HasVerticalAlignment.ALIGN_MIDDLE);
		this.titleWidget.getTop().setCellHorizontalAlignment(learnButton, HasHorizontalAlignment.ALIGN_LEFT);

		// this.app = app;
		VerticalPanel mainPanel = new VerticalPanel();
		mainPanel.add(this.titleWidget);

		learnButton.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				app.learningWasExecutedOnce = true;
				busyLearnButton();
				app.getWorkerService().learn(new ArrayList<ExampleDTO>(positiveExampleDTOs.values()),
						new ArrayList<ExampleDTO>(negativeExampleDTOs.values()),
						new AsyncCallback<LearnedConceptDTO>() {

							public void onSuccess(LearnedConceptDTO dto) {
								app.displayLearnedConcept(dto);
								enableLearnButton();
							}

							public void onFailure(Throwable arg0) {
								app.reportError(arg0);
								enableLearnButton();
							}
						});

			}
		});
		learnButton.setEnabled(false);

		Label posTitle = new Label("Positive Samples");
		posTitle.addStyleName("module-subtitle");
		mainPanel.add(posTitle);

		// positive List
		mainPanel.add(positiveExampleTable);

		Label negTitle = new Label("Negative Samples");
		negTitle.addStyleName("module-subtitle");
		mainPanel.add(negTitle);

		// negative List
		mainPanel.add(negativeExampleTable);

		mainPanel.addStyleName("module-border");
		mainPanel.setWidth("95%");
		mainPanel.addStyleName("greyed");
		draw();
		initWidget(mainPanel);

	}

	public void draw() {

		// flush tables
		positiveExampleTable.clear();
		negativeExampleTable.clear();

		// add content
		addExamplesToPosNegTable(positiveExampleDTOs, positiveExampleTable);
		addExamplesToPosNegTable(negativeExampleDTOs, negativeExampleTable);

	}

	public void addPositive(ExampleDTO dto) {
		positiveExampleDTOs.put(dto.getUri(), dto);
		checkLearnButton();
		draw();

	}

	public void addNegative(ExampleDTO dto) {
		negativeExampleDTOs.put(dto.getUri(), dto);
		checkLearnButton();
		draw();

	}

	private void checkLearnButton() {
		if (negativeExampleDTOs.size() > 0 && positiveExampleDTOs.size() > 0) {
			learnButton.setText(learnButtonLabelEnabled);
			learnButton.setEnabled(true);
		} else {
			insufficientExamplesLearnButton();
		}
	}

	private void enableLearnButton() {
		checkLearnButton();
	}

	private void busyLearnButton() {
		learnButton.setText(learnButtonLabelLearning);
		learnButton.setEnabled(false);
	}

	private void insufficientExamplesLearnButton() {
		learnButton.setText(learnButtonLabelInsufficientExamples);
		learnButton.setEnabled(false);
	}

	private void addExamplesToPosNegTable(final Map<String, ExampleDTO> exampleDTOs, VerticalPanel table) {
		ExampleWidget.addExamplesToPosNegTable(exampleDTOs, table);

	}

	public boolean contains(ExampleDTO exampleDTO) {
		return this.negativeExampleDTOs.containsKey(exampleDTO.getUri())
				|| this.positiveExampleDTOs.containsKey(exampleDTO.getUri());
	}
	
	public void load(MyExamples examples){
		negativeExampleDTOs.clear();
		positiveExampleDTOs.clear();
		
		if(examples!=null){
			if(examples.getNegatives()!=null){
				for (ExampleDTO nExamp : examples.getNegatives()) {
					negativeExampleDTOs.put(nExamp.getUri(), nExamp);
				}
				
			}
			
			if(examples.getNegatives()!=null){
				for (ExampleDTO pExamp : examples.getPositives()) {
					positiveExampleDTOs.put(pExamp.getUri(), pExamp);
				}
				
			}	
		}
		
		draw();
	}
	
	
	

}
